home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / rpc3.9 / part02 < prev    next >
Encoding:
Internet Message Format  |  1988-02-27  |  59.3 KB

  1. Subject:  v13i079:  Sun RPC, release 3.9, Part02/15
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Stephen X. Nahm <sxn@Sun.COM>
  7. Posting-number: Volume 13, Issue 79
  8. Archive-name: rpc3.9/part02
  9.  
  10.  
  11. #! /bin/sh
  12. # This is a shell archive. To extract, remove the header and type "sh filename"
  13. #
  14. cd rpc
  15. echo x - clnt_raw.c
  16. cat > clnt_raw.c <<'Funky_Stuff'
  17. /* @(#)clnt_raw.c    1.2 87/11/09 3.9 RPCSRC */
  18. /*
  19.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  20.  * unrestricted use provided that this legend is included on all tape
  21.  * media and as a part of the software program in whole or part.  Users
  22.  * may copy or modify Sun RPC without charge, but are not authorized
  23.  * to license or distribute it to anyone else except as part of a product or
  24.  * program developed by the user.
  25.  * 
  26.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  27.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  28.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  29.  * 
  30.  * Sun RPC is provided with no support and without any obligation on the
  31.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  32.  * modification or enhancement.
  33.  * 
  34.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  35.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  36.  * OR ANY PART THEREOF.
  37.  * 
  38.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  39.  * or profits or other special, indirect and consequential damages, even if
  40.  * Sun has been advised of the possibility of such damages.
  41.  * 
  42.  * Sun Microsystems, Inc.
  43.  * 2550 Garcia Avenue
  44.  * Mountain View, California  94043
  45.  */
  46. #if !defined(lint) && defined(SCCSIDS)
  47. static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
  48. #endif
  49.  
  50. /*
  51.  * clnt_raw.c
  52.  *
  53.  * Copyright (C) 1984, Sun Microsystems, Inc.
  54.  *
  55.  * Memory based rpc for simple testing and timing.
  56.  * Interface to create an rpc client and server in the same process.
  57.  * This lets us similate rpc and get round trip overhead, without
  58.  * any interference from the kernal.
  59.  */
  60.  
  61. #include <rpc/rpc.h>
  62. #include <sys/time.h>
  63.  
  64. #define MCALL_MSG_SIZE 24
  65.  
  66. /*
  67.  * This is the "network" we will be moving stuff over.
  68.  */
  69. static struct clntraw_private {
  70.     CLIENT    client_object;
  71.     XDR    xdr_stream;
  72.     char    _raw_buf[UDPMSGSIZE];
  73.     char    mashl_callmsg[MCALL_MSG_SIZE];
  74.     u_int    mcnt;
  75. } *clntraw_private;
  76.  
  77. static enum clnt_stat    clntraw_call();
  78. static void        clntraw_abort();
  79. static void        clntraw_geterr();
  80. static bool_t        clntraw_freeres();
  81. static bool_t        clntraw_control();
  82. static void        clntraw_destroy();
  83.  
  84. static struct clnt_ops client_ops = {
  85.     clntraw_call,
  86.     clntraw_abort,
  87.     clntraw_geterr,
  88.     clntraw_freeres,
  89.     clntraw_destroy,
  90.     clntraw_control
  91. };
  92.  
  93. void    svc_getreq();
  94.  
  95. /*
  96.  * Create a client handle for memory based rpc.
  97.  */
  98. CLIENT *
  99. clntraw_create(prog, vers)
  100.     u_long prog;
  101.     u_long vers;
  102. {
  103.     register struct clntraw_private *clp = clntraw_private;
  104.     struct rpc_msg call_msg;
  105.     XDR *xdrs = &clp->xdr_stream;
  106.     CLIENT    *client = &clp->client_object;
  107.  
  108.     if (clp == 0) {
  109.         clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
  110.         if (clp == 0)
  111.             return (0);
  112.         clntraw_private = clp;
  113.     }
  114.     /*
  115.      * pre-serialize the staic part of the call msg and stash it away
  116.      */
  117.     call_msg.rm_direction = CALL;
  118.     call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
  119.     call_msg.rm_call.cb_prog = prog;
  120.     call_msg.rm_call.cb_vers = vers;
  121.     xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); 
  122.     if (! xdr_callhdr(xdrs, &call_msg)) {
  123.         perror("clnt_raw.c - Fatal header serialization error.");
  124.     }
  125.     clp->mcnt = XDR_GETPOS(xdrs);
  126.     XDR_DESTROY(xdrs);
  127.  
  128.     /*
  129.      * Set xdrmem for client/server shared buffer
  130.      */
  131.     xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
  132.  
  133.     /*
  134.      * create client handle
  135.      */
  136.     client->cl_ops = &client_ops;
  137.     client->cl_auth = authnone_create();
  138.     return (client);
  139. }
  140.  
  141. static enum clnt_stat 
  142. clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
  143.     CLIENT *h;
  144.     u_long proc;
  145.     xdrproc_t xargs;
  146.     caddr_t argsp;
  147.     xdrproc_t xresults;
  148.     caddr_t resultsp;
  149.     struct timeval timeout;
  150. {
  151.     register struct clntraw_private *clp = clntraw_private;
  152.     register XDR *xdrs = &clp->xdr_stream;
  153.     struct rpc_msg msg;
  154.     enum clnt_stat status;
  155.     struct rpc_err error;
  156.  
  157.     if (clp == 0)
  158.         return (RPC_FAILED);
  159. call_again:
  160.     /*
  161.      * send request
  162.      */
  163.     xdrs->x_op = XDR_ENCODE;
  164.     XDR_SETPOS(xdrs, 0);
  165.     ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
  166.     if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
  167.         (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
  168.         (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
  169.         (! (*xargs)(xdrs, argsp))) {
  170.         return (RPC_CANTENCODEARGS);
  171.     }
  172.     (void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
  173.  
  174.     /*
  175.      * We have to call server input routine here because this is
  176.      * all going on in one process. Yuk.
  177.      */
  178.     svc_getreq(1);
  179.  
  180.     /*
  181.      * get results
  182.      */
  183.     xdrs->x_op = XDR_DECODE;
  184.     XDR_SETPOS(xdrs, 0);
  185.     msg.acpted_rply.ar_verf = _null_auth;
  186.     msg.acpted_rply.ar_results.where = resultsp;
  187.     msg.acpted_rply.ar_results.proc = xresults;
  188.     if (! xdr_replymsg(xdrs, &msg))
  189.         return (RPC_CANTDECODERES);
  190.     _seterr_reply(&msg, &error);
  191.     status = error.re_status;
  192.  
  193.     if (status == RPC_SUCCESS) {
  194.         if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
  195.             status = RPC_AUTHERROR;
  196.         }
  197.     }  /* end successful completion */
  198.     else {
  199.         if (AUTH_REFRESH(h->cl_auth))
  200.             goto call_again;
  201.     }  /* end of unsuccessful completion */
  202.  
  203.     if (status == RPC_SUCCESS) {
  204.         if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
  205.             status = RPC_AUTHERROR;
  206.         }
  207.         if (msg.acpted_rply.ar_verf.oa_base != NULL) {
  208.             xdrs->x_op = XDR_FREE;
  209.             (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
  210.         }
  211.     }
  212.  
  213.     return (status);
  214. }
  215.  
  216. static void
  217. clntraw_geterr()
  218. {
  219. }
  220.  
  221.  
  222. static bool_t
  223. clntraw_freeres(cl, xdr_res, res_ptr)
  224.     CLIENT *cl;
  225.     xdrproc_t xdr_res;
  226.     caddr_t res_ptr;
  227. {
  228.     register struct clntraw_private *clp = clntraw_private;
  229.     register XDR *xdrs = &clp->xdr_stream;
  230.     bool_t rval;
  231.  
  232.     if (clp == 0)
  233.     {
  234.         rval = (bool_t) RPC_FAILED;
  235.         return (rval);
  236.     }
  237.     xdrs->x_op = XDR_FREE;
  238.     return ((*xdr_res)(xdrs, res_ptr));
  239. }
  240.  
  241. static void
  242. clntraw_abort()
  243. {
  244. }
  245.  
  246. static bool_t
  247. clntraw_control()
  248. {
  249.     return (FALSE);
  250. }
  251.  
  252. static void
  253. clntraw_destroy()
  254. {
  255. }
  256. Funky_Stuff
  257. len=`wc -c < clnt_raw.c`
  258. if [ $len !=     5845 ] ; then
  259.   echo error: clnt_raw.c was $len bytes long, should have been     5845
  260. fi
  261. echo x - clnt_simple.c
  262. cat > clnt_simple.c <<'Funky_Stuff'
  263. /* @(#)clnt_simple.c    1.1 87/11/04 3.9 RPCSRC */
  264. /*
  265.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  266.  * unrestricted use provided that this legend is included on all tape
  267.  * media and as a part of the software program in whole or part.  Users
  268.  * may copy or modify Sun RPC without charge, but are not authorized
  269.  * to license or distribute it to anyone else except as part of a product or
  270.  * program developed by the user.
  271.  * 
  272.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  273.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  274.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  275.  * 
  276.  * Sun RPC is provided with no support and without any obligation on the
  277.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  278.  * modification or enhancement.
  279.  * 
  280.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  281.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  282.  * OR ANY PART THEREOF.
  283.  * 
  284.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  285.  * or profits or other special, indirect and consequential damages, even if
  286.  * Sun has been advised of the possibility of such damages.
  287.  * 
  288.  * Sun Microsystems, Inc.
  289.  * 2550 Garcia Avenue
  290.  * Mountain View, California  94043
  291.  */
  292. #if !defined(lint) && defined(SCCSIDS)
  293. static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
  294. #endif
  295.  
  296. /* 
  297.  * clnt_simple.c
  298.  * Simplified front end to rpc.
  299.  *
  300.  * Copyright (C) 1984, Sun Microsystems, Inc.
  301.  */
  302.  
  303. #include <stdio.h>
  304. #include <rpc/rpc.h>
  305. #include <sys/socket.h>
  306. #include <sys/time.h>
  307. #include <netdb.h>
  308. #include <strings.h>
  309.  
  310. static struct callrpc_private {
  311.     CLIENT    *client;
  312.     int    socket;
  313.     int    oldprognum, oldversnum, valid;
  314.     char    *oldhost;
  315. } *callrpc_private;
  316.  
  317. callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
  318.     char *host;
  319.     xdrproc_t inproc, outproc;
  320.     char *in, *out;
  321. {
  322.     register struct callrpc_private *crp = callrpc_private;
  323.     struct sockaddr_in server_addr;
  324.     enum clnt_stat clnt_stat;
  325.     struct hostent *hp;
  326.     struct timeval timeout, tottimeout;
  327.  
  328.     if (crp == 0) {
  329.         crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
  330.         if (crp == 0)
  331.             return (0);
  332.         callrpc_private = crp;
  333.     }
  334.     if (crp->oldhost == NULL) {
  335.         crp->oldhost = malloc(256);
  336.         crp->oldhost[0] = 0;
  337.         crp->socket = RPC_ANYSOCK;
  338.     }
  339.     if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
  340.         && strcmp(crp->oldhost, host) == 0) {
  341.         /* reuse old client */        
  342.     } else {
  343.         crp->valid = 0;
  344.         (void)close(crp->socket);
  345.         crp->socket = RPC_ANYSOCK;
  346.         if (crp->client) {
  347.             clnt_destroy(crp->client);
  348.             crp->client = NULL;
  349.         }
  350.         if ((hp = gethostbyname(host)) == NULL)
  351.             return ((int) RPC_UNKNOWNHOST);
  352.         timeout.tv_usec = 0;
  353.         timeout.tv_sec = 5;
  354.         bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
  355.         server_addr.sin_family = AF_INET;
  356.         server_addr.sin_port =  0;
  357.         if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
  358.             (u_long)versnum, timeout, &crp->socket)) == NULL)
  359.             return ((int) rpc_createerr.cf_stat);
  360.         crp->valid = 1;
  361.         crp->oldprognum = prognum;
  362.         crp->oldversnum = versnum;
  363.         (void) strcpy(crp->oldhost, host);
  364.     }
  365.     tottimeout.tv_sec = 25;
  366.     tottimeout.tv_usec = 0;
  367.     clnt_stat = clnt_call(crp->client, procnum, inproc, in,
  368.         outproc, out, tottimeout);
  369.     /* 
  370.      * if call failed, empty cache
  371.      */
  372.     if (clnt_stat != RPC_SUCCESS)
  373.         crp->valid = 0;
  374.     return ((int) clnt_stat);
  375. }
  376. Funky_Stuff
  377. len=`wc -c < clnt_simple.c`
  378. if [ $len !=     3463 ] ; then
  379.   echo error: clnt_simple.c was $len bytes long, should have been     3463
  380. fi
  381. echo x - clnt_tcp.c
  382. cat > clnt_tcp.c <<'Funky_Stuff'
  383. /* @(#)clnt_tcp.c    1.2 87/11/09 3.9 RPCSRC */
  384. /*
  385.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  386.  * unrestricted use provided that this legend is included on all tape
  387.  * media and as a part of the software program in whole or part.  Users
  388.  * may copy or modify Sun RPC without charge, but are not authorized
  389.  * to license or distribute it to anyone else except as part of a product or
  390.  * program developed by the user.
  391.  * 
  392.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  393.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  394.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  395.  * 
  396.  * Sun RPC is provided with no support and without any obligation on the
  397.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  398.  * modification or enhancement.
  399.  * 
  400.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  401.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  402.  * OR ANY PART THEREOF.
  403.  * 
  404.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  405.  * or profits or other special, indirect and consequential damages, even if
  406.  * Sun has been advised of the possibility of such damages.
  407.  * 
  408.  * Sun Microsystems, Inc.
  409.  * 2550 Garcia Avenue
  410.  * Mountain View, California  94043
  411.  */
  412. #if !defined(lint) && defined(SCCSIDS)
  413. static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
  414. #endif
  415.  
  416. /*
  417.  * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
  418.  *
  419.  * Copyright (C) 1984, Sun Microsystems, Inc.
  420.  *
  421.  * TCP based RPC supports 'batched calls'.
  422.  * A sequence of calls may be batched-up in a send buffer.  The rpc call
  423.  * return immediately to the client even though the call was not necessarily
  424.  * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
  425.  * the rpc timeout value is zero (see clnt.h, rpc).
  426.  *
  427.  * Clients should NOT casually batch calls that in fact return results; that is,
  428.  * the server side should be aware that a call is batched and not produce any
  429.  * return message.  Batched calls that produce many result messages can
  430.  * deadlock (netlock) the client and the server....
  431.  *
  432.  * Now go hang yourself.
  433.  */
  434.  
  435. #include <stdio.h>
  436. #include <rpc/rpc.h>
  437. #include <sys/socket.h>
  438. #include <sys/time.h>
  439. #include <netdb.h>
  440. #include <errno.h>
  441. #include <rpc/pmap_clnt.h>
  442.  
  443. #define MCALL_MSG_SIZE 24
  444.  
  445. extern int errno;
  446.  
  447. static int    readtcp();
  448. static int    writetcp();
  449.  
  450. static enum clnt_stat    clnttcp_call();
  451. static void        clnttcp_abort();
  452. static void        clnttcp_geterr();
  453. static bool_t        clnttcp_freeres();
  454. static bool_t           clnttcp_control();
  455. static void        clnttcp_destroy();
  456.  
  457. static struct clnt_ops tcp_ops = {
  458.     clnttcp_call,
  459.     clnttcp_abort,
  460.     clnttcp_geterr,
  461.     clnttcp_freeres,
  462.     clnttcp_destroy,
  463.     clnttcp_control
  464. };
  465.  
  466. struct ct_data {
  467.     int        ct_sock;
  468.     bool_t        ct_closeit;
  469.     struct timeval    ct_wait;
  470.     bool_t          ct_waitset;       /* wait set by clnt_control? */
  471.     struct sockaddr_in ct_addr; 
  472.     struct rpc_err    ct_error;
  473.     char        ct_mcall[MCALL_MSG_SIZE];    /* marshalled callmsg */
  474.     u_int        ct_mpos;            /* pos after marshal */
  475.     XDR        ct_xdrs;
  476. };
  477.  
  478. /*
  479.  * Create a client handle for a tcp/ip connection.
  480.  * If *sockp<0, *sockp is set to a newly created TCP socket and it is
  481.  * connected to raddr.  If *sockp non-negative then
  482.  * raddr is ignored.  The rpc/tcp package does buffering
  483.  * similar to stdio, so the client must pick send and receive buffer sizes,];
  484.  * 0 => use the default.
  485.  * If raddr->sin_port is 0, then a binder on the remote machine is
  486.  * consulted for the right port number.
  487.  * NB: *sockp is copied into a private area.
  488.  * NB: It is the clients responsibility to close *sockp.
  489.  * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
  490.  * something more useful.
  491.  */
  492. CLIENT *
  493. clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
  494.     struct sockaddr_in *raddr;
  495.     u_long prog;
  496.     u_long vers;
  497.     register int *sockp;
  498.     u_int sendsz;
  499.     u_int recvsz;
  500. {
  501.     CLIENT *h;
  502.     register struct ct_data *ct;
  503.     struct timeval now;
  504.     struct rpc_msg call_msg;
  505.  
  506.     h  = (CLIENT *)mem_alloc(sizeof(*h));
  507.     if (h == NULL) {
  508.         (void)fprintf(stderr, "clnttcp_create: out of memory\n");
  509.         rpc_createerr.cf_stat = RPC_SYSTEMERROR;
  510.         rpc_createerr.cf_error.re_errno = errno;
  511.         goto fooy;
  512.     }
  513.     ct = (struct ct_data *)mem_alloc(sizeof(*ct));
  514.     if (ct == NULL) {
  515.         (void)fprintf(stderr, "clnttcp_create: out of memory\n");
  516.         rpc_createerr.cf_stat = RPC_SYSTEMERROR;
  517.         rpc_createerr.cf_error.re_errno = errno;
  518.         goto fooy;
  519.     }
  520.  
  521.     /*
  522.      * If no port number given ask the pmap for one
  523.      */
  524.     if (raddr->sin_port == 0) {
  525.         u_short port;
  526.         if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
  527.             mem_free((caddr_t)ct, sizeof(struct ct_data));
  528.             mem_free((caddr_t)h, sizeof(CLIENT));
  529.             return ((CLIENT *)NULL);
  530.         }
  531.         raddr->sin_port = htons(port);
  532.     }
  533.  
  534.     /*
  535.      * If no socket given, open one
  536.      */
  537.     if (*sockp < 0) {
  538.         *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  539.         (void)bindresvport(*sockp, (struct sockaddr_in *)0);
  540.         if ((*sockp < 0)
  541.             || (connect(*sockp, (struct sockaddr *)raddr,
  542.             sizeof(*raddr)) < 0)) {
  543.             rpc_createerr.cf_stat = RPC_SYSTEMERROR;
  544.             rpc_createerr.cf_error.re_errno = errno;
  545.             (void)close(*sockp);
  546.             goto fooy;
  547.         }
  548.         ct->ct_closeit = TRUE;
  549.     } else {
  550.         ct->ct_closeit = FALSE;
  551.     }
  552.  
  553.     /*
  554.      * Set up private data struct
  555.      */
  556.     ct->ct_sock = *sockp;
  557.     ct->ct_wait.tv_usec = 0;
  558.     ct->ct_waitset = FALSE;
  559.     ct->ct_addr = *raddr;
  560.  
  561.     /*
  562.      * Initialize call message
  563.      */
  564.     (void)gettimeofday(&now, (struct timezone *)0);
  565.     call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
  566.     call_msg.rm_direction = CALL;
  567.     call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
  568.     call_msg.rm_call.cb_prog = prog;
  569.     call_msg.rm_call.cb_vers = vers;
  570.  
  571.     /*
  572.      * pre-serialize the staic part of the call msg and stash it away
  573.      */
  574.     xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
  575.         XDR_ENCODE);
  576.     if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
  577.         if (ct->ct_closeit) {
  578.             (void)close(*sockp);
  579.         }
  580.         goto fooy;
  581.     }
  582.     ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
  583.     XDR_DESTROY(&(ct->ct_xdrs));
  584.  
  585.     /*
  586.      * Create a client handle which uses xdrrec for serialization
  587.      * and authnone for authentication.
  588.      */
  589.     xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
  590.         (caddr_t)ct, readtcp, writetcp);
  591.     h->cl_ops = &tcp_ops;
  592.     h->cl_private = (caddr_t) ct;
  593.     h->cl_auth = authnone_create();
  594.     return (h);
  595.  
  596. fooy:
  597.     /*
  598.      * Something goofed, free stuff and barf
  599.      */
  600.     mem_free((caddr_t)ct, sizeof(struct ct_data));
  601.     mem_free((caddr_t)h, sizeof(CLIENT));
  602.     return ((CLIENT *)NULL);
  603. }
  604.  
  605. static enum clnt_stat
  606. clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
  607.     register CLIENT *h;
  608.     u_long proc;
  609.     xdrproc_t xdr_args;
  610.     caddr_t args_ptr;
  611.     xdrproc_t xdr_results;
  612.     caddr_t results_ptr;
  613.     struct timeval timeout;
  614. {
  615.     register struct ct_data *ct = (struct ct_data *) h->cl_private;
  616.     register XDR *xdrs = &(ct->ct_xdrs);
  617.     struct rpc_msg reply_msg;
  618.     u_long x_id;
  619.     u_long *msg_x_id = (u_long *)(ct->ct_mcall);    /* yuk */
  620.     register bool_t shipnow;
  621.     int refreshes = 2;
  622.  
  623.     if (!ct->ct_waitset) {
  624.         ct->ct_wait = timeout;
  625.     }
  626.  
  627.     shipnow =
  628.         (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
  629.         && timeout.tv_usec == 0) ? FALSE : TRUE;
  630.  
  631. call_again:
  632.     xdrs->x_op = XDR_ENCODE;
  633.     ct->ct_error.re_status = RPC_SUCCESS;
  634.     x_id = ntohl(--(*msg_x_id));
  635.     if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
  636.         (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
  637.         (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
  638.         (! (*xdr_args)(xdrs, args_ptr))) {
  639.         if (ct->ct_error.re_status == RPC_SUCCESS)
  640.             ct->ct_error.re_status = RPC_CANTENCODEARGS;
  641.         (void)xdrrec_endofrecord(xdrs, TRUE);
  642.         return (ct->ct_error.re_status);
  643.     }
  644.     if (! xdrrec_endofrecord(xdrs, shipnow))
  645.         return (ct->ct_error.re_status = RPC_CANTSEND);
  646.     if (! shipnow)
  647.         return (RPC_SUCCESS);
  648.     /*
  649.      * Hack to provide rpc-based message passing
  650.      */
  651.     if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
  652.         return(ct->ct_error.re_status = RPC_TIMEDOUT);
  653.     }
  654.  
  655.  
  656.     /*
  657.      * Keep receiving until we get a valid transaction id
  658.      */
  659.     xdrs->x_op = XDR_DECODE;
  660.     while (TRUE) {
  661.         reply_msg.acpted_rply.ar_verf = _null_auth;
  662.         reply_msg.acpted_rply.ar_results.where = NULL;
  663.         reply_msg.acpted_rply.ar_results.proc = xdr_void;
  664.         if (! xdrrec_skiprecord(xdrs))
  665.             return (ct->ct_error.re_status);
  666.         /* now decode and validate the response header */
  667.         if (! xdr_replymsg(xdrs, &reply_msg)) {
  668.             if (ct->ct_error.re_status == RPC_SUCCESS)
  669.                 continue;
  670.             return (ct->ct_error.re_status);
  671.         }
  672.         if (reply_msg.rm_xid == x_id)
  673.             break;
  674.     }
  675.  
  676.     /*
  677.      * process header
  678.      */
  679.     _seterr_reply(&reply_msg, &(ct->ct_error));
  680.     if (ct->ct_error.re_status == RPC_SUCCESS) {
  681.         if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
  682.             ct->ct_error.re_status = RPC_AUTHERROR;
  683.             ct->ct_error.re_why = AUTH_INVALIDRESP;
  684.         } else if (! (*xdr_results)(xdrs, results_ptr)) {
  685.             if (ct->ct_error.re_status == RPC_SUCCESS)
  686.                 ct->ct_error.re_status = RPC_CANTDECODERES;
  687.         }
  688.         /* free verifier ... */
  689.         if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
  690.             xdrs->x_op = XDR_FREE;
  691.             (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
  692.         }
  693.     }  /* end successful completion */
  694.     else {
  695.         /* maybe our credentials need to be refreshed ... */
  696.         if (refreshes-- && AUTH_REFRESH(h->cl_auth))
  697.             goto call_again;
  698.     }  /* end of unsuccessful completion */
  699.     return (ct->ct_error.re_status);
  700. }
  701.  
  702. static void
  703. clnttcp_geterr(h, errp)
  704.     CLIENT *h;
  705.     struct rpc_err *errp;
  706. {
  707.     register struct ct_data *ct =
  708.         (struct ct_data *) h->cl_private;
  709.  
  710.     *errp = ct->ct_error;
  711. }
  712.  
  713. static bool_t
  714. clnttcp_freeres(cl, xdr_res, res_ptr)
  715.     CLIENT *cl;
  716.     xdrproc_t xdr_res;
  717.     caddr_t res_ptr;
  718. {
  719.     register struct ct_data *ct = (struct ct_data *)cl->cl_private;
  720.     register XDR *xdrs = &(ct->ct_xdrs);
  721.  
  722.     xdrs->x_op = XDR_FREE;
  723.     return ((*xdr_res)(xdrs, res_ptr));
  724. }
  725.  
  726. static void
  727. clnttcp_abort()
  728. {
  729. }
  730.  
  731. static bool_t
  732. clnttcp_control(cl, request, info)
  733.     CLIENT *cl;
  734.     int request;
  735.     char *info;
  736. {
  737.     register struct ct_data *ct = (struct ct_data *)cl->cl_private;
  738.  
  739.     switch (request) {
  740.     case CLSET_TIMEOUT:
  741.         ct->ct_wait = *(struct timeval *)info;
  742.         ct->ct_waitset = TRUE;
  743.         break;
  744.     case CLGET_TIMEOUT:
  745.         *(struct timeval *)info = ct->ct_wait;
  746.         break;
  747.     case CLGET_SERVER_ADDR:
  748.         *(struct sockaddr_in *)info = ct->ct_addr;
  749.         break;
  750.     default:
  751.         return (FALSE);
  752.     }
  753.     return (TRUE);
  754. }
  755.  
  756.  
  757. static void
  758. clnttcp_destroy(h)
  759.     CLIENT *h;
  760. {
  761.     register struct ct_data *ct =
  762.         (struct ct_data *) h->cl_private;
  763.  
  764.     if (ct->ct_closeit) {
  765.         (void)close(ct->ct_sock);
  766.     }
  767.     XDR_DESTROY(&(ct->ct_xdrs));
  768.     mem_free((caddr_t)ct, sizeof(struct ct_data));
  769.     mem_free((caddr_t)h, sizeof(CLIENT));
  770. }
  771.  
  772. /*
  773.  * Interface between xdr serializer and tcp connection.
  774.  * Behaves like the system calls, read & write, but keeps some error state
  775.  * around for the rpc level.
  776.  */
  777. static int
  778. readtcp(ct, buf, len)
  779.     register struct ct_data *ct;
  780.     caddr_t buf;
  781.     register int len;
  782. {
  783. #ifdef FD_SETSIZE
  784.     fd_set mask;
  785.     fd_set readfds;
  786.  
  787.     if (len == 0)
  788.         return (0);
  789.     FD_ZERO(&mask);
  790.     FD_SET(ct->ct_sock, &mask);
  791. #else
  792.     register int mask = 1 << (ct->ct_sock);
  793.     int readfds;
  794.  
  795.     if (len == 0)
  796.         return (0);
  797.  
  798. #endif /* def FD_SETSIZE */
  799.     while (TRUE) {
  800.         readfds = mask;
  801.         switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
  802.                    &(ct->ct_wait))) {
  803.         case 0:
  804.             ct->ct_error.re_status = RPC_TIMEDOUT;
  805.             return (-1);
  806.  
  807.         case -1:
  808.             if (errno == EINTR)
  809.                 continue;
  810.             ct->ct_error.re_status = RPC_CANTRECV;
  811.             ct->ct_error.re_errno = errno;
  812.             return (-1);
  813.         }
  814.         break;
  815.     }
  816.     switch (len = read(ct->ct_sock, buf, len)) {
  817.  
  818.     case 0:
  819.         /* premature eof */
  820.         ct->ct_error.re_errno = ECONNRESET;
  821.         ct->ct_error.re_status = RPC_CANTRECV;
  822.         len = -1;  /* it's really an error */
  823.         break;
  824.  
  825.     case -1:
  826.         ct->ct_error.re_errno = errno;
  827.         ct->ct_error.re_status = RPC_CANTRECV;
  828.         break;
  829.     }
  830.     return (len);
  831. }
  832.  
  833. static int
  834. writetcp(ct, buf, len)
  835.     struct ct_data *ct;
  836.     caddr_t buf;
  837.     int len;
  838. {
  839.     register int i, cnt;
  840.  
  841.     for (cnt = len; cnt > 0; cnt -= i, buf += i) {
  842.         if ((i = write(ct->ct_sock, buf, cnt)) == -1) {
  843.             ct->ct_error.re_errno = errno;
  844.             ct->ct_error.re_status = RPC_CANTSEND;
  845.             return (-1);
  846.         }
  847.     }
  848.     return (len);
  849. }
  850. Funky_Stuff
  851. len=`wc -c < clnt_tcp.c`
  852. if [ $len !=    12089 ] ; then
  853.   echo error: clnt_tcp.c was $len bytes long, should have been    12089
  854. fi
  855. echo x - clnt_udp.c
  856. cat > clnt_udp.c <<'Funky_Stuff'
  857. /* @(#)clnt_udp.c    1.2 87/11/09 3.9 RPCSRC */
  858. /*
  859.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  860.  * unrestricted use provided that this legend is included on all tape
  861.  * media and as a part of the software program in whole or part.  Users
  862.  * may copy or modify Sun RPC without charge, but are not authorized
  863.  * to license or distribute it to anyone else except as part of a product or
  864.  * program developed by the user.
  865.  * 
  866.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  867.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  868.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  869.  * 
  870.  * Sun RPC is provided with no support and without any obligation on the
  871.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  872.  * modification or enhancement.
  873.  * 
  874.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  875.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  876.  * OR ANY PART THEREOF.
  877.  * 
  878.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  879.  * or profits or other special, indirect and consequential damages, even if
  880.  * Sun has been advised of the possibility of such damages.
  881.  * 
  882.  * Sun Microsystems, Inc.
  883.  * 2550 Garcia Avenue
  884.  * Mountain View, California  94043
  885.  */
  886. #if !defined(lint) && defined(SCCSIDS)
  887. static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
  888. #endif
  889.  
  890. /*
  891.  * clnt_udp.c, Implements a UDP/IP based, client side RPC.
  892.  *
  893.  * Copyright (C) 1984, Sun Microsystems, Inc.
  894.  */
  895.  
  896. #include <stdio.h>
  897. #include <rpc/rpc.h>
  898. #include <sys/socket.h>
  899. #include <sys/time.h>
  900. #include <sys/ioctl.h>
  901. #include <netdb.h>
  902. #include <errno.h>
  903. #include <rpc/pmap_clnt.h>
  904.  
  905. extern int errno;
  906.  
  907. /*
  908.  * UDP bases client side rpc operations
  909.  */
  910. static enum clnt_stat    clntudp_call();
  911. static void        clntudp_abort();
  912. static void        clntudp_geterr();
  913. static bool_t        clntudp_freeres();
  914. static bool_t           clntudp_control();
  915. static void        clntudp_destroy();
  916.  
  917. static struct clnt_ops udp_ops = {
  918.     clntudp_call,
  919.     clntudp_abort,
  920.     clntudp_geterr,
  921.     clntudp_freeres,
  922.     clntudp_destroy,
  923.     clntudp_control
  924. };
  925.  
  926. /* 
  927.  * Private data kept per client handle
  928.  */
  929. struct cu_data {
  930.     int           cu_sock;
  931.     bool_t           cu_closeit;
  932.     struct sockaddr_in cu_raddr;
  933.     int           cu_rlen;
  934.     struct timeval       cu_wait;
  935.     struct timeval     cu_total;
  936.     struct rpc_err       cu_error;
  937.     XDR           cu_outxdrs;
  938.     u_int           cu_xdrpos;
  939.     u_int           cu_sendsz;
  940.     char           *cu_outbuf;
  941.     u_int           cu_recvsz;
  942.     char           cu_inbuf[1];
  943. };
  944.  
  945. /*
  946.  * Create a UDP based client handle.
  947.  * If *sockp<0, *sockp is set to a newly created UPD socket.
  948.  * If raddr->sin_port is 0 a binder on the remote machine
  949.  * is consulted for the correct port number.
  950.  * NB: It is the clients responsibility to close *sockp.
  951.  * NB: The rpch->cl_auth is initialized to null authentication.
  952.  *     Caller may wish to set this something more useful.
  953.  *
  954.  * wait is the amount of time used between retransmitting a call if
  955.  * no response has been heard;  retransmition occurs until the actual
  956.  * rpc call times out.
  957.  *
  958.  * sendsz and recvsz are the maximum allowable packet sizes that can be
  959.  * sent and received.
  960.  */
  961. CLIENT *
  962. clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
  963.     struct sockaddr_in *raddr;
  964.     u_long program;
  965.     u_long version;
  966.     struct timeval wait;
  967.     register int *sockp;
  968.     u_int sendsz;
  969.     u_int recvsz;
  970. {
  971.     CLIENT *cl;
  972.     register struct cu_data *cu;
  973.     struct timeval now;
  974.     struct rpc_msg call_msg;
  975.  
  976.     cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
  977.     if (cl == NULL) {
  978.         (void) fprintf(stderr, "clntudp_create: out of memory\n");
  979.         rpc_createerr.cf_stat = RPC_SYSTEMERROR;
  980.         rpc_createerr.cf_error.re_errno = errno;
  981.         goto fooy;
  982.     }
  983.     sendsz = ((sendsz + 3) / 4) * 4;
  984.     recvsz = ((recvsz + 3) / 4) * 4;
  985.     cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
  986.     if (cu == NULL) {
  987.         (void) fprintf(stderr, "clntudp_create: out of memory\n");
  988.         rpc_createerr.cf_stat = RPC_SYSTEMERROR;
  989.         rpc_createerr.cf_error.re_errno = errno;
  990.         goto fooy;
  991.     }
  992.     cu->cu_outbuf = &cu->cu_inbuf[recvsz];
  993.  
  994.     (void)gettimeofday(&now, (struct timezone *)0);
  995.     if (raddr->sin_port == 0) {
  996.         u_short port;
  997.         if ((port =
  998.             pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
  999.             goto fooy;
  1000.         }
  1001.         raddr->sin_port = htons(port);
  1002.     }
  1003.     cl->cl_ops = &udp_ops;
  1004.     cl->cl_private = (caddr_t)cu;
  1005.     cu->cu_raddr = *raddr;
  1006.     cu->cu_rlen = sizeof (cu->cu_raddr);
  1007.     cu->cu_wait = wait;
  1008.     cu->cu_total.tv_sec = -1;
  1009.     cu->cu_total.tv_usec = -1;
  1010.     cu->cu_sendsz = sendsz;
  1011.     cu->cu_recvsz = recvsz;
  1012.     call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
  1013.     call_msg.rm_direction = CALL;
  1014.     call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
  1015.     call_msg.rm_call.cb_prog = program;
  1016.     call_msg.rm_call.cb_vers = version;
  1017.     xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
  1018.         sendsz, XDR_ENCODE);
  1019.     if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
  1020.         goto fooy;
  1021.     }
  1022.     cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
  1023.     if (*sockp < 0) {
  1024.         int dontblock = 1;
  1025.  
  1026.         *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  1027.         if (*sockp < 0) {
  1028.             rpc_createerr.cf_stat = RPC_SYSTEMERROR;
  1029.             rpc_createerr.cf_error.re_errno = errno;
  1030.             goto fooy;
  1031.         }
  1032.         /* attempt to bind to prov port */
  1033.         (void)bindresvport(*sockp, (struct sockaddr_in *)0);
  1034.         /* the sockets rpc controls are non-blocking */
  1035.         (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
  1036.         cu->cu_closeit = TRUE;
  1037.     } else {
  1038.         cu->cu_closeit = FALSE;
  1039.     }
  1040.     cu->cu_sock = *sockp;
  1041.     cl->cl_auth = authnone_create();
  1042.     return (cl);
  1043. fooy:
  1044.     if (cu)
  1045.         mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
  1046.     if (cl)
  1047.         mem_free((caddr_t)cl, sizeof(CLIENT));
  1048.     return ((CLIENT *)NULL);
  1049. }
  1050.  
  1051. CLIENT *
  1052. clntudp_create(raddr, program, version, wait, sockp)
  1053.     struct sockaddr_in *raddr;
  1054.     u_long program;
  1055.     u_long version;
  1056.     struct timeval wait;
  1057.     register int *sockp;
  1058. {
  1059.  
  1060.     return(clntudp_bufcreate(raddr, program, version, wait, sockp,
  1061.         UDPMSGSIZE, UDPMSGSIZE));
  1062. }
  1063.  
  1064. static enum clnt_stat 
  1065. clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
  1066.     register CLIENT    *cl;        /* client handle */
  1067.     u_long        proc;        /* procedure number */
  1068.     xdrproc_t    xargs;        /* xdr routine for args */
  1069.     caddr_t        argsp;        /* pointer to args */
  1070.     xdrproc_t    xresults;    /* xdr routine for results */
  1071.     caddr_t        resultsp;    /* pointer to results */
  1072.     struct timeval    utimeout;    /* seconds to wait before giving up */
  1073. {
  1074.     register struct cu_data *cu = (struct cu_data *)cl->cl_private;
  1075.     register XDR *xdrs;
  1076.     register int outlen;
  1077.     register int inlen;
  1078.     int fromlen;
  1079. #ifdef FD_SETSIZE
  1080.     fd_set readfds;
  1081.     fd_set mask;
  1082. #else
  1083.     int readfds;
  1084.     register int mask;
  1085. #endif /* def FD_SETSIZE */
  1086.     struct sockaddr_in from;
  1087.     struct rpc_msg reply_msg;
  1088.     XDR reply_xdrs;
  1089.     struct timeval time_waited;
  1090.     bool_t ok;
  1091.     int nrefreshes = 2;    /* number of times to refresh cred */
  1092.     struct timeval timeout;
  1093.  
  1094.     if (cu->cu_total.tv_usec == -1) {
  1095.         timeout = utimeout;     /* use supplied timeout */
  1096.     } else {
  1097.         timeout = cu->cu_total; /* use default timeout */
  1098.     }
  1099.  
  1100.     time_waited.tv_sec = 0;
  1101.     time_waited.tv_usec = 0;
  1102. call_again:
  1103.     xdrs = &(cu->cu_outxdrs);
  1104.     xdrs->x_op = XDR_ENCODE;
  1105.     XDR_SETPOS(xdrs, cu->cu_xdrpos);
  1106.     /*
  1107.      * the transaction is the first thing in the out buffer
  1108.      */
  1109.     (*(u_short *)(cu->cu_outbuf))++;
  1110.     if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
  1111.         (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
  1112.         (! (*xargs)(xdrs, argsp)))
  1113.         return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
  1114.     outlen = (int)XDR_GETPOS(xdrs);
  1115.  
  1116. send_again:
  1117.     if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
  1118.         (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
  1119.         != outlen) {
  1120.         cu->cu_error.re_errno = errno;
  1121.         return (cu->cu_error.re_status = RPC_CANTSEND);
  1122.     }
  1123.  
  1124.     /*
  1125.      * Hack to provide rpc-based message passing
  1126.      */
  1127.     if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
  1128.         return (cu->cu_error.re_status = RPC_TIMEDOUT);
  1129.     }
  1130.     /*
  1131.      * sub-optimal code appears here because we have
  1132.      * some clock time to spare while the packets are in flight.
  1133.      * (We assume that this is actually only executed once.)
  1134.      */
  1135.     reply_msg.acpted_rply.ar_verf = _null_auth;
  1136.     reply_msg.acpted_rply.ar_results.where = resultsp;
  1137.     reply_msg.acpted_rply.ar_results.proc = xresults;
  1138. #ifdef FD_SETSIZE
  1139.     FD_ZERO(&mask);
  1140.     FD_SET(cu->cu_sock, &mask);
  1141. #else
  1142.     mask = 1 << cu->cu_sock;
  1143. #endif /* def FD_SETSIZE */
  1144.     for (;;) {
  1145.         readfds = mask;
  1146.         switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, 
  1147.                    (int *)NULL, &(cu->cu_wait))) {
  1148.  
  1149.         case 0:
  1150.             time_waited.tv_sec += cu->cu_wait.tv_sec;
  1151.             time_waited.tv_usec += cu->cu_wait.tv_usec;
  1152.             while (time_waited.tv_usec >= 1000000) {
  1153.                 time_waited.tv_sec++;
  1154.                 time_waited.tv_usec -= 1000000;
  1155.             }
  1156.             if ((time_waited.tv_sec < timeout.tv_sec) ||
  1157.                 ((time_waited.tv_sec == timeout.tv_sec) &&
  1158.                 (time_waited.tv_usec < timeout.tv_usec)))
  1159.                 goto send_again;    
  1160.             return (cu->cu_error.re_status = RPC_TIMEDOUT);
  1161.  
  1162.         /*
  1163.          * buggy in other cases because time_waited is not being
  1164.          * updated.
  1165.          */
  1166.         case -1:
  1167.             if (errno == EINTR)
  1168.                 continue;    
  1169.             cu->cu_error.re_errno = errno;
  1170.             return (cu->cu_error.re_status = RPC_CANTRECV);
  1171.         }
  1172.         do {
  1173.             fromlen = sizeof(struct sockaddr);
  1174.             inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, 
  1175.                 (int) cu->cu_recvsz, 0,
  1176.                 (struct sockaddr *)&from, &fromlen);
  1177.         } while (inlen < 0 && errno == EINTR);
  1178.         if (inlen < 0) {
  1179.             if (errno == EWOULDBLOCK)
  1180.                 continue;    
  1181.             cu->cu_error.re_errno = errno;
  1182.             return (cu->cu_error.re_status = RPC_CANTRECV);
  1183.         }
  1184.         if (inlen < sizeof(u_long))
  1185.             continue;    
  1186.         /* see if reply transaction id matches sent id */
  1187.         if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf)))
  1188.             continue;    
  1189.         /* we now assume we have the proper reply */
  1190.         break;
  1191.     }
  1192.  
  1193.     /*
  1194.      * now decode and validate the response
  1195.      */
  1196.     xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
  1197.     ok = xdr_replymsg(&reply_xdrs, &reply_msg);
  1198.     /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
  1199.     if (ok) {
  1200.         _seterr_reply(&reply_msg, &(cu->cu_error));
  1201.         if (cu->cu_error.re_status == RPC_SUCCESS) {
  1202.             if (! AUTH_VALIDATE(cl->cl_auth,
  1203.                 &reply_msg.acpted_rply.ar_verf)) {
  1204.                 cu->cu_error.re_status = RPC_AUTHERROR;
  1205.                 cu->cu_error.re_why = AUTH_INVALIDRESP;
  1206.             }
  1207.             if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
  1208.                 xdrs->x_op = XDR_FREE;
  1209.                 (void)xdr_opaque_auth(xdrs,
  1210.                     &(reply_msg.acpted_rply.ar_verf));
  1211.             } 
  1212.         }  /* end successful completion */
  1213.         else {
  1214.             /* maybe our credentials need to be refreshed ... */
  1215.             if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
  1216.                 nrefreshes--;
  1217.                 goto call_again;
  1218.             }
  1219.         }  /* end of unsuccessful completion */
  1220.     }  /* end of valid reply message */
  1221.     else {
  1222.         cu->cu_error.re_status = RPC_CANTDECODERES;
  1223.     }
  1224.     return (cu->cu_error.re_status);
  1225. }
  1226.  
  1227. static void
  1228. clntudp_geterr(cl, errp)
  1229.     CLIENT *cl;
  1230.     struct rpc_err *errp;
  1231. {
  1232.     register struct cu_data *cu = (struct cu_data *)cl->cl_private;
  1233.  
  1234.     *errp = cu->cu_error;
  1235. }
  1236.  
  1237.  
  1238. static bool_t
  1239. clntudp_freeres(cl, xdr_res, res_ptr)
  1240.     CLIENT *cl;
  1241.     xdrproc_t xdr_res;
  1242.     caddr_t res_ptr;
  1243. {
  1244.     register struct cu_data *cu = (struct cu_data *)cl->cl_private;
  1245.     register XDR *xdrs = &(cu->cu_outxdrs);
  1246.  
  1247.     xdrs->x_op = XDR_FREE;
  1248.     return ((*xdr_res)(xdrs, res_ptr));
  1249. }
  1250.  
  1251. static void 
  1252. clntudp_abort(/*h*/)
  1253.     /*CLIENT *h;*/
  1254. {
  1255. }
  1256.  
  1257. static bool_t
  1258. clntudp_control(cl, request, info)
  1259.     CLIENT *cl;
  1260.     int request;
  1261.     char *info;
  1262. {
  1263.     register struct cu_data *cu = (struct cu_data *)cl->cl_private;
  1264.  
  1265.     switch (request) {
  1266.     case CLSET_TIMEOUT:
  1267.         cu->cu_total = *(struct timeval *)info;
  1268.         break;
  1269.     case CLGET_TIMEOUT:
  1270.         *(struct timeval *)info = cu->cu_total;
  1271.         break;
  1272.     case CLSET_RETRY_TIMEOUT:
  1273.         cu->cu_wait = *(struct timeval *)info;
  1274.         break;
  1275.     case CLGET_RETRY_TIMEOUT:
  1276.         *(struct timeval *)info = cu->cu_wait;
  1277.         break;
  1278.     case CLGET_SERVER_ADDR:
  1279.         *(struct sockaddr_in *)info = cu->cu_raddr;
  1280.         break;
  1281.     default:
  1282.         return (FALSE);
  1283.     }
  1284.     return (TRUE);
  1285. }
  1286.     
  1287. static void
  1288. clntudp_destroy(cl)
  1289.     CLIENT *cl;
  1290. {
  1291.     register struct cu_data *cu = (struct cu_data *)cl->cl_private;
  1292.  
  1293.     if (cu->cu_closeit) {
  1294.         (void)close(cu->cu_sock);
  1295.     }
  1296.     XDR_DESTROY(&(cu->cu_outxdrs));
  1297.     mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
  1298.     mem_free((caddr_t)cl, sizeof(CLIENT));
  1299. }
  1300. Funky_Stuff
  1301. len=`wc -c < clnt_udp.c`
  1302. if [ $len !=    12060 ] ; then
  1303.   echo error: clnt_udp.c was $len bytes long, should have been    12060
  1304. fi
  1305. echo x - get_myaddress.c
  1306. cat > get_myaddress.c <<'Funky_Stuff'
  1307. /* @(#)get_myaddress.c    1.1 87/11/04 3.9 RPCSRC */
  1308. /*
  1309.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1310.  * unrestricted use provided that this legend is included on all tape
  1311.  * media and as a part of the software program in whole or part.  Users
  1312.  * may copy or modify Sun RPC without charge, but are not authorized
  1313.  * to license or distribute it to anyone else except as part of a product or
  1314.  * program developed by the user.
  1315.  * 
  1316.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1317.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1318.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1319.  * 
  1320.  * Sun RPC is provided with no support and without any obligation on the
  1321.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1322.  * modification or enhancement.
  1323.  * 
  1324.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1325.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1326.  * OR ANY PART THEREOF.
  1327.  * 
  1328.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1329.  * or profits or other special, indirect and consequential damages, even if
  1330.  * Sun has been advised of the possibility of such damages.
  1331.  * 
  1332.  * Sun Microsystems, Inc.
  1333.  * 2550 Garcia Avenue
  1334.  * Mountain View, California  94043
  1335.  */
  1336. #if !defined(lint) && defined(SCCSIDS)
  1337. static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";
  1338. #endif
  1339.  
  1340. /*
  1341.  * get_myaddress.c
  1342.  *
  1343.  * Get client's IP address via ioctl.  This avoids using the yellowpages.
  1344.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1345.  */
  1346.  
  1347. #include <rpc/types.h>
  1348. #include <rpc/pmap_prot.h>
  1349. #include <sys/socket.h>
  1350. #include <stdio.h>
  1351. #include <net/if.h>
  1352. #include <sys/ioctl.h>
  1353. #include <arpa/inet.h>
  1354. #include <netinet/in.h>
  1355.  
  1356. /* 
  1357.  * don't use gethostbyname, which would invoke yellow pages
  1358.  */
  1359. get_myaddress(addr)
  1360.     struct sockaddr_in *addr;
  1361. {
  1362.     int s;
  1363.     char buf[BUFSIZ];
  1364.     struct ifconf ifc;
  1365.     struct ifreq ifreq, *ifr;
  1366.     int len;
  1367.  
  1368.     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  1369.         perror("get_myaddress: socket");
  1370.         exit(1);
  1371.     }
  1372.     ifc.ifc_len = sizeof (buf);
  1373.     ifc.ifc_buf = buf;
  1374.     if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
  1375.         perror("get_myaddress: ioctl (get interface configuration)");
  1376.         exit(1);
  1377.     }
  1378.     ifr = ifc.ifc_req;
  1379.     for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
  1380.         ifreq = *ifr;
  1381.         if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
  1382.             perror("get_myaddress: ioctl");
  1383.             exit(1);
  1384.         }
  1385.         if ((ifreq.ifr_flags & IFF_UP) &&
  1386.             ifr->ifr_addr.sa_family == AF_INET) {
  1387.             *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
  1388.             addr->sin_port = htons(PMAPPORT);
  1389.             break;
  1390.         }
  1391.         ifr++;
  1392.     }
  1393.     (void) close(s);
  1394. }
  1395. Funky_Stuff
  1396. len=`wc -c < get_myaddress.c`
  1397. if [ $len !=     2668 ] ; then
  1398.   echo error: get_myaddress.c was $len bytes long, should have been     2668
  1399. fi
  1400. echo x - getrpcent.c
  1401. cat > getrpcent.c <<'Funky_Stuff'
  1402. /* @(#)getrpcent.c    1.4 87/11/13 3.9 RPCSRC */
  1403. #if !defined(lint) && defined(SCCSIDS)
  1404. static  char sccsid[] = "@(#)getrpcent.c 1.9 87/08/11  Copyr 1984 Sun Micro";
  1405. #endif
  1406.  
  1407. /*
  1408.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1409.  * unrestricted use provided that this legend is included on all tape
  1410.  * media and as a part of the software program in whole or part.  Users
  1411.  * may copy or modify Sun RPC without charge, but are not authorized
  1412.  * to license or distribute it to anyone else except as part of a product or
  1413.  * program developed by the user.
  1414.  * 
  1415.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1416.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1417.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1418.  * 
  1419.  * Sun RPC is provided with no support and without any obligation on the
  1420.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1421.  * modification or enhancement.
  1422.  * 
  1423.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1424.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1425.  * OR ANY PART THEREOF.
  1426.  * 
  1427.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1428.  * or profits or other special, indirect and consequential damages, even if
  1429.  * Sun has been advised of the possibility of such damages.
  1430.  * 
  1431.  * Sun Microsystems, Inc.
  1432.  * 2550 Garcia Avenue
  1433.  * Mountain View, California  94043
  1434.  */
  1435.  
  1436. /*
  1437.  * Copyright (c) 1985 by Sun Microsystems, Inc.
  1438.  */
  1439.  
  1440. #include <stdio.h>
  1441. #include <sys/types.h>
  1442. #include <rpc/rpc.h>
  1443. #include <netdb.h>
  1444. #include <sys/socket.h>
  1445.  
  1446. /*
  1447.  * Internet version.
  1448.  */
  1449. struct rpcdata {
  1450.     FILE    *rpcf;
  1451.     char    *current;
  1452.     int    currentlen;
  1453.     int    stayopen;
  1454. #define    MAXALIASES    35
  1455.     char    *rpc_aliases[MAXALIASES];
  1456.     struct    rpcent rpc;
  1457.     char    line[BUFSIZ+1];
  1458.     char    *domain;
  1459. } *rpcdata, *_rpcdata();
  1460.  
  1461. static    struct rpcent *interpret();
  1462. struct    hostent *gethostent();
  1463. char    *inet_ntoa();
  1464. static    char *index();
  1465.  
  1466. static char RPCDB[] = "/etc/rpc";
  1467.  
  1468. static struct rpcdata *
  1469. _rpcdata()
  1470. {
  1471.     register struct rpcdata *d = rpcdata;
  1472.  
  1473.     if (d == 0) {
  1474.         d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
  1475.         rpcdata = d;
  1476.     }
  1477.     return (d);
  1478. }
  1479.  
  1480. struct rpcent *
  1481. getrpcbynumber(number)
  1482.     register int number;
  1483. {
  1484.     register struct rpcdata *d = _rpcdata();
  1485.     register struct rpcent *p;
  1486.     int reason;
  1487.     char adrstr[10], *val = NULL;
  1488.     int vallen;
  1489.  
  1490.     if (d == 0)
  1491.         return (0);
  1492.     setrpcent(0);
  1493.     while (p = getrpcent()) {
  1494.         if (p->r_number == number)
  1495.             break;
  1496.     }
  1497.     endrpcent();
  1498.     return (p);
  1499. }
  1500.  
  1501. struct rpcent *
  1502. getrpcbyname(name)
  1503.     char *name;
  1504. {
  1505.     struct rpcent *rpc;
  1506.     char **rp;
  1507.  
  1508.     setrpcent(0);
  1509.     while(rpc = getrpcent()) {
  1510.         if (strcmp(rpc->r_name, name) == 0)
  1511.             return (rpc);
  1512.         for (rp = rpc->r_aliases; *rp != NULL; rp++) {
  1513.             if (strcmp(*rp, name) == 0)
  1514.                 return (rpc);
  1515.         }
  1516.     }
  1517.     endrpcent();
  1518.     return (NULL);
  1519. }
  1520.  
  1521. setrpcent(f)
  1522.     int f;
  1523. {
  1524.     register struct rpcdata *d = _rpcdata();
  1525.  
  1526.     if (d == 0)
  1527.         return;
  1528.     if (d->rpcf == NULL)
  1529.         d->rpcf = fopen(RPCDB, "r");
  1530.     else
  1531.         rewind(d->rpcf);
  1532.     if (d->current)
  1533.         free(d->current);
  1534.     d->current = NULL;
  1535.     d->stayopen |= f;
  1536. }
  1537.  
  1538. endrpcent()
  1539. {
  1540.     register struct rpcdata *d = _rpcdata();
  1541.  
  1542.     if (d == 0)
  1543.         return;
  1544.     if (d->current && !d->stayopen) {
  1545.         free(d->current);
  1546.         d->current = NULL;
  1547.     }
  1548.     if (d->rpcf && !d->stayopen) {
  1549.         fclose(d->rpcf);
  1550.         d->rpcf = NULL;
  1551.     }
  1552. }
  1553.  
  1554. struct rpcent *
  1555. getrpcent()
  1556. {
  1557.     struct rpcent *hp;
  1558.     int reason;
  1559.     char *key = NULL, *val = NULL;
  1560.     int keylen, vallen;
  1561.     register struct rpcdata *d = _rpcdata();
  1562.  
  1563.     if (d == 0)
  1564.         return;
  1565.     if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
  1566.         return (NULL);
  1567.     if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
  1568.         return (NULL);
  1569.     return interpret(d->line, strlen(d->line));
  1570. }
  1571.  
  1572. static struct rpcent *
  1573. interpret(val, len)
  1574. {
  1575.     register struct rpcdata *d = _rpcdata();
  1576.     char *p;
  1577.     register char *cp, **q;
  1578.  
  1579.     if (d == 0)
  1580.         return;
  1581.     strncpy(d->line, val, len);
  1582.     p = d->line;
  1583.     d->line[len] = '\n';
  1584.     if (*p == '#')
  1585.         return (getrpcent());
  1586.     cp = index(p, '#');
  1587.     if (cp == NULL)
  1588.     {
  1589.         cp = index(p, '\n');
  1590.         if (cp == NULL)
  1591.             return (getrpcent());
  1592.     }
  1593.     *cp = '\0';
  1594.     cp = index(p, ' ');
  1595.     if (cp == NULL)
  1596.     {
  1597.         cp = index(p, '\t');
  1598.         if (cp == NULL)
  1599.             return (getrpcent());
  1600.     }
  1601.     *cp++ = '\0';
  1602.     /* THIS STUFF IS INTERNET SPECIFIC */
  1603.     d->rpc.r_name = d->line;
  1604.     while (*cp == ' ' || *cp == '\t')
  1605.         cp++;
  1606.     d->rpc.r_number = atoi(cp);
  1607.     q = d->rpc.r_aliases = d->rpc_aliases;
  1608.     cp = index(p, ' ');
  1609.     if (cp != NULL)
  1610.         *cp++ = '\0';
  1611.     else
  1612.     {
  1613.         cp = index(p, '\t');
  1614.         if (cp != NULL)
  1615.             *cp++ = '\0';
  1616.     }
  1617.     while (cp && *cp) {
  1618.         if (*cp == ' ' || *cp == '\t') {
  1619.             cp++;
  1620.             continue;
  1621.         }
  1622.         if (q < &(d->rpc_aliases[MAXALIASES - 1]))
  1623.             *q++ = cp;
  1624.         cp = index(p, ' ');
  1625.         if (cp != NULL)
  1626.             *cp++ = '\0';
  1627.         else
  1628.         {
  1629.             cp = index(p, '\t');
  1630.             if (cp != NULL)
  1631.                 *cp++ = '\0';
  1632.         }
  1633.     }
  1634.     *q = NULL;
  1635.     return (&d->rpc);
  1636. }
  1637. Funky_Stuff
  1638. len=`wc -c < getrpcent.c`
  1639. if [ $len !=     4805 ] ; then
  1640.   echo error: getrpcent.c was $len bytes long, should have been     4805
  1641. fi
  1642. echo x - getrpcport.c
  1643. cat > getrpcport.c <<'Funky_Stuff'
  1644. /* @(#)getrpcport.c    1.2 87/11/13 3.9 RPCSRC */
  1645. #if !defined(lint) && defined(SCCSIDS)
  1646. static  char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI";
  1647. #endif
  1648. /*
  1649.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1650.  * unrestricted use provided that this legend is included on all tape
  1651.  * media and as a part of the software program in whole or part.  Users
  1652.  * may copy or modify Sun RPC without charge, but are not authorized
  1653.  * to license or distribute it to anyone else except as part of a product or
  1654.  * program developed by the user.
  1655.  * 
  1656.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1657.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1658.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1659.  * 
  1660.  * Sun RPC is provided with no support and without any obligation on the
  1661.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1662.  * modification or enhancement.
  1663.  * 
  1664.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1665.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1666.  * OR ANY PART THEREOF.
  1667.  * 
  1668.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1669.  * or profits or other special, indirect and consequential damages, even if
  1670.  * Sun has been advised of the possibility of such damages.
  1671.  * 
  1672.  * Sun Microsystems, Inc.
  1673.  * 2550 Garcia Avenue
  1674.  * Mountain View, California  94043
  1675.  */
  1676.  
  1677. /*
  1678.  * Copyright (c) 1985 by Sun Microsystems, Inc.
  1679.  */
  1680.  
  1681. #include <stdio.h>
  1682. #include <rpc/rpc.h>
  1683. #include <netdb.h>
  1684. #include <sys/socket.h>
  1685.  
  1686. getrpcport(host, prognum, versnum, proto)
  1687.     char *host;
  1688. {
  1689.     struct sockaddr_in addr;
  1690.     struct hostent *hp;
  1691.  
  1692.     if ((hp = gethostbyname(host)) == NULL)
  1693.         return (0);
  1694.     bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length);
  1695.     addr.sin_family = AF_INET;
  1696.     addr.sin_port =  0;
  1697.     return (pmap_getport(&addr, prognum, versnum, proto));
  1698. }
  1699. Funky_Stuff
  1700. len=`wc -c < getrpcport.c`
  1701. if [ $len !=     1890 ] ; then
  1702.   echo error: getrpcport.c was $len bytes long, should have been     1890
  1703. fi
  1704. echo x - netdb.h
  1705. cat > netdb.h <<'Funky_Stuff'
  1706. /* @(#)netdb.h    1.1 87/11/13 3.9 RPCSRC */
  1707. /*
  1708.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1709.  * unrestricted use provided that this legend is included on all tape
  1710.  * media and as a part of the software program in whole or part.  Users
  1711.  * may copy or modify Sun RPC without charge, but are not authorized
  1712.  * to license or distribute it to anyone else except as part of a product or
  1713.  * program developed by the user.
  1714.  * 
  1715.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1716.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1717.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1718.  * 
  1719.  * Sun RPC is provided with no support and without any obligation on the
  1720.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1721.  * modification or enhancement.
  1722.  *
  1723.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1724.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1725.  * OR ANY PART THEREOF.
  1726.  * 
  1727.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1728.  * or profits or other special, indirect and consequential damages, even if
  1729.  * Sun has been advised of the possibility of such damages.
  1730.  * 
  1731.  * Sun Microsystems, Inc.
  1732.  * 2550 Garcia Avenue
  1733.  * Mountain View, California  94043
  1734.  */
  1735. /*    @(#)rpc.h 1.8 87/07/24 SMI    */
  1736.  
  1737. /* Really belongs in <netdb.h> */
  1738.  
  1739. struct rpcent {
  1740.       char    *r_name;        /* name of server for this rpc program */
  1741.       char    **r_aliases;    /* alias list */
  1742.       int     r_number;       /* rpc program number */
  1743. };
  1744.  
  1745. struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent();
  1746. Funky_Stuff
  1747. len=`wc -c < netdb.h`
  1748. if [ $len !=     1637 ] ; then
  1749.   echo error: netdb.h was $len bytes long, should have been     1637
  1750. fi
  1751. echo x - pmap_clnt.c
  1752. cat > pmap_clnt.c <<'Funky_Stuff'
  1753. /* @(#)pmap_clnt.c    1.1 87/11/04 3.9 RPCSRC */
  1754. /*
  1755.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1756.  * unrestricted use provided that this legend is included on all tape
  1757.  * media and as a part of the software program in whole or part.  Users
  1758.  * may copy or modify Sun RPC without charge, but are not authorized
  1759.  * to license or distribute it to anyone else except as part of a product or
  1760.  * program developed by the user.
  1761.  * 
  1762.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1763.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1764.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1765.  * 
  1766.  * Sun RPC is provided with no support and without any obligation on the
  1767.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1768.  * modification or enhancement.
  1769.  * 
  1770.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1771.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1772.  * OR ANY PART THEREOF.
  1773.  * 
  1774.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1775.  * or profits or other special, indirect and consequential damages, even if
  1776.  * Sun has been advised of the possibility of such damages.
  1777.  * 
  1778.  * Sun Microsystems, Inc.
  1779.  * 2550 Garcia Avenue
  1780.  * Mountain View, California  94043
  1781.  */
  1782. #if !defined(lint) && defined(SCCSIDS)
  1783. static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";
  1784. #endif
  1785.  
  1786. /*
  1787.  * pmap_clnt.c
  1788.  * Client interface to pmap rpc service.
  1789.  *
  1790.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1791.  */
  1792.  
  1793. #include <rpc/rpc.h>
  1794. #include <rpc/pmap_prot.h>
  1795. #include <rpc/pmap_clnt.h>
  1796. #include <sys/time.h>
  1797.  
  1798. static struct timeval timeout = { 5, 0 };
  1799. static struct timeval tottimeout = { 60, 0 };
  1800.  
  1801. void clnt_perror();
  1802.  
  1803.  
  1804. /*
  1805.  * Set a mapping between program,version and port.
  1806.  * Calls the pmap service remotely to do the mapping.
  1807.  */
  1808. bool_t
  1809. pmap_set(program, version, protocol, port)
  1810.     u_long program;
  1811.     u_long version;
  1812.     int protocol;
  1813.     u_short port;
  1814. {
  1815.     struct sockaddr_in myaddress;
  1816.     int socket = -1;
  1817.     register CLIENT *client;
  1818.     struct pmap parms;
  1819.     bool_t rslt;
  1820.  
  1821.     get_myaddress(&myaddress);
  1822.     client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
  1823.         timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
  1824.     if (client == (CLIENT *)NULL)
  1825.         return (FALSE);
  1826.     parms.pm_prog = program;
  1827.     parms.pm_vers = version;
  1828.     parms.pm_prot = protocol;
  1829.     parms.pm_port = port;
  1830.     if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
  1831.         tottimeout) != RPC_SUCCESS) {
  1832.         clnt_perror(client, "Cannot register service");
  1833.         return (FALSE);
  1834.     }
  1835.     CLNT_DESTROY(client);
  1836.     (void)close(socket);
  1837.     return (rslt);
  1838. }
  1839.  
  1840. /*
  1841.  * Remove the mapping between program,version and port.
  1842.  * Calls the pmap service remotely to do the un-mapping.
  1843.  */
  1844. bool_t
  1845. pmap_unset(program, version)
  1846.     u_long program;
  1847.     u_long version;
  1848. {
  1849.     struct sockaddr_in myaddress;
  1850.     int socket = -1;
  1851.     register CLIENT *client;
  1852.     struct pmap parms;
  1853.     bool_t rslt;
  1854.  
  1855.     get_myaddress(&myaddress);
  1856.     client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
  1857.         timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
  1858.     if (client == (CLIENT *)NULL)
  1859.         return (FALSE);
  1860.     parms.pm_prog = program;
  1861.     parms.pm_vers = version;
  1862.     parms.pm_port = parms.pm_prot = 0;
  1863.     CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
  1864.         tottimeout);
  1865.     CLNT_DESTROY(client);
  1866.     (void)close(socket);
  1867.     return (rslt);
  1868. }
  1869. Funky_Stuff
  1870. len=`wc -c < pmap_clnt.c`
  1871. if [ $len !=     3374 ] ; then
  1872.   echo error: pmap_clnt.c was $len bytes long, should have been     3374
  1873. fi
  1874. echo x - pmap_clnt.h
  1875. cat > pmap_clnt.h <<'Funky_Stuff'
  1876. /* @(#)pmap_clnt.h    1.1 87/11/04 3.9 RPCSRC */
  1877. /*
  1878.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1879.  * unrestricted use provided that this legend is included on all tape
  1880.  * media and as a part of the software program in whole or part.  Users
  1881.  * may copy or modify Sun RPC without charge, but are not authorized
  1882.  * to license or distribute it to anyone else except as part of a product or
  1883.  * program developed by the user.
  1884.  * 
  1885.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1886.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1887.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1888.  * 
  1889.  * Sun RPC is provided with no support and without any obligation on the
  1890.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1891.  * modification or enhancement.
  1892.  * 
  1893.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1894.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1895.  * OR ANY PART THEREOF.
  1896.  * 
  1897.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1898.  * or profits or other special, indirect and consequential damages, even if
  1899.  * Sun has been advised of the possibility of such damages.
  1900.  * 
  1901.  * Sun Microsystems, Inc.
  1902.  * 2550 Garcia Avenue
  1903.  * Mountain View, California  94043
  1904.  */
  1905. /*    @(#)pmap_clnt.h 1.10 86/07/16 SMI    */
  1906.  
  1907. /*
  1908.  * pmap_clnt.h
  1909.  * Supplies C routines to get to portmap services.
  1910.  *
  1911.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1912.  */
  1913.  
  1914. /*
  1915.  * Usage:
  1916.  *    success = pmap_set(program, version, protocol, port);
  1917.  *    success = pmap_unset(program, version);
  1918.  *    port = pmap_getport(address, program, version, protocol);
  1919.  *    head = pmap_getmaps(address);
  1920.  *    clnt_stat = pmap_rmtcall(address, program, version, procedure,
  1921.  *        xdrargs, argsp, xdrres, resp, tout, port_ptr)
  1922.  *        (works for udp only.) 
  1923.  *     clnt_stat = clnt_broadcast(program, version, procedure,
  1924.  *        xdrargs, argsp,    xdrres, resp, eachresult)
  1925.  *        (like pmap_rmtcall, except the call is broadcasted to all
  1926.  *        locally connected nets.  For each valid response received,
  1927.  *        the procedure eachresult is called.  Its form is:
  1928.  *    done = eachresult(resp, raddr)
  1929.  *        bool_t done;
  1930.  *        caddr_t resp;
  1931.  *        struct sockaddr_in raddr;
  1932.  *        where resp points to the results of the call and raddr is the
  1933.  *        address if the responder to the broadcast.
  1934.  */
  1935.  
  1936. extern bool_t        pmap_set();
  1937. extern bool_t        pmap_unset();
  1938. extern struct pmaplist    *pmap_getmaps();
  1939. enum clnt_stat        pmap_rmtcall();
  1940. enum clnt_stat        clnt_broadcast();
  1941. extern u_short        pmap_getport();
  1942. Funky_Stuff
  1943. len=`wc -c < pmap_clnt.h`
  1944. if [ $len !=     2525 ] ; then
  1945.   echo error: pmap_clnt.h was $len bytes long, should have been     2525
  1946. fi
  1947. echo x - pmap_getmaps.c
  1948. cat > pmap_getmaps.c <<'Funky_Stuff'
  1949. /* @(#)pmap_getmaps.c    1.1 87/11/04 3.9 RPCSRC */
  1950. /*
  1951.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1952.  * unrestricted use provided that this legend is included on all tape
  1953.  * media and as a part of the software program in whole or part.  Users
  1954.  * may copy or modify Sun RPC without charge, but are not authorized
  1955.  * to license or distribute it to anyone else except as part of a product or
  1956.  * program developed by the user.
  1957.  * 
  1958.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1959.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1960.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1961.  * 
  1962.  * Sun RPC is provided with no support and without any obligation on the
  1963.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1964.  * modification or enhancement.
  1965.  * 
  1966.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1967.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1968.  * OR ANY PART THEREOF.
  1969.  * 
  1970.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1971.  * or profits or other special, indirect and consequential damages, even if
  1972.  * Sun has been advised of the possibility of such damages.
  1973.  * 
  1974.  * Sun Microsystems, Inc.
  1975.  * 2550 Garcia Avenue
  1976.  * Mountain View, California  94043
  1977.  */
  1978. #if !defined(lint) && defined(SCCSIDS)
  1979. static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
  1980. #endif
  1981.  
  1982. /*
  1983.  * pmap_getmap.c
  1984.  * Client interface to pmap rpc service.
  1985.  * contains pmap_getmaps, which is only tcp service involved
  1986.  *
  1987.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1988.  */
  1989.  
  1990. #include <rpc/rpc.h>
  1991. #include <rpc/pmap_prot.h>
  1992. #include <rpc/pmap_clnt.h>
  1993. #include <sys/socket.h>
  1994. #include <sys/time.h>
  1995. #include <netdb.h>
  1996. #include <stdio.h>
  1997. #include <errno.h>
  1998. #include <net/if.h>
  1999. #include <sys/ioctl.h>
  2000. #define NAMELEN 255
  2001. #define MAX_BROADCAST_SIZE 1400
  2002.  
  2003. extern int errno;
  2004.  
  2005. /*
  2006.  * Get a copy of the current port maps.
  2007.  * Calls the pmap service remotely to do get the maps.
  2008.  */
  2009. struct pmaplist *
  2010. pmap_getmaps(address)
  2011.      struct sockaddr_in *address;
  2012. {
  2013.     struct pmaplist *head = (struct pmaplist *)NULL;
  2014.     int socket = -1;
  2015.     struct timeval minutetimeout;
  2016.     register CLIENT *client;
  2017.  
  2018.     minutetimeout.tv_sec = 60;
  2019.     minutetimeout.tv_usec = 0;
  2020.     address->sin_port = htons(PMAPPORT);
  2021.     client = clnttcp_create(address, PMAPPROG,
  2022.         PMAPVERS, &socket, 50, 500);
  2023.     if (client != (CLIENT *)NULL) {
  2024.         if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
  2025.             &head, minutetimeout) != RPC_SUCCESS) {
  2026.             clnt_perror(client, "pmap_getmaps rpc problem");
  2027.         }
  2028.         CLNT_DESTROY(client);
  2029.     }
  2030.     (void)close(socket);
  2031.     address->sin_port = 0;
  2032.     return (head);
  2033. }
  2034. Funky_Stuff
  2035. len=`wc -c < pmap_getmaps.c`
  2036. if [ $len !=     2682 ] ; then
  2037.   echo error: pmap_getmaps.c was $len bytes long, should have been     2682
  2038. fi
  2039. echo x - pmap_getport.c
  2040. cat > pmap_getport.c <<'Funky_Stuff'
  2041. /* @(#)pmap_getport.c    1.1 87/11/04 3.9 RPCSRC */
  2042. /*
  2043.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  2044.  * unrestricted use provided that this legend is included on all tape
  2045.  * media and as a part of the software program in whole or part.  Users
  2046.  * may copy or modify Sun RPC without charge, but are not authorized
  2047.  * to license or distribute it to anyone else except as part of a product or
  2048.  * program developed by the user.
  2049.  * 
  2050.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  2051.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  2052.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  2053.  * 
  2054.  * Sun RPC is provided with no support and without any obligation on the
  2055.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  2056.  * modification or enhancement.
  2057.  * 
  2058.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  2059.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  2060.  * OR ANY PART THEREOF.
  2061.  * 
  2062.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  2063.  * or profits or other special, indirect and consequential damages, even if
  2064.  * Sun has been advised of the possibility of such damages.
  2065.  * 
  2066.  * Sun Microsystems, Inc.
  2067.  * 2550 Garcia Avenue
  2068.  * Mountain View, California  94043
  2069.  */
  2070. #if !defined(lint) && defined(SCCSIDS)
  2071. static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";
  2072. #endif
  2073.  
  2074. /*
  2075.  * pmap_getport.c
  2076.  * Client interface to pmap rpc service.
  2077.  *
  2078.  * Copyright (C) 1984, Sun Microsystems, Inc.
  2079.  */
  2080.  
  2081. #include <rpc/rpc.h>
  2082. #include <rpc/pmap_prot.h>
  2083. #include <rpc/pmap_clnt.h>
  2084. #include <sys/socket.h>
  2085. #include <sys/time.h>
  2086. #include <net/if.h>
  2087.  
  2088. static struct timeval timeout = { 5, 0 };
  2089. static struct timeval tottimeout = { 60, 0 };
  2090.  
  2091. /*
  2092.  * Find the mapped port for program,version.
  2093.  * Calls the pmap service remotely to do the lookup.
  2094.  * Returns 0 if no map exists.
  2095.  */
  2096. u_short
  2097. pmap_getport(address, program, version, protocol)
  2098.     struct sockaddr_in *address;
  2099.     u_long program;
  2100.     u_long version;
  2101.     u_int protocol;
  2102. {
  2103.     u_short port = 0;
  2104.     int socket = -1;
  2105.     register CLIENT *client;
  2106.     struct pmap parms;
  2107.  
  2108.     address->sin_port = htons(PMAPPORT);
  2109.     client = clntudp_bufcreate(address, PMAPPROG,
  2110.         PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
  2111.     if (client != (CLIENT *)NULL) {
  2112.         parms.pm_prog = program;
  2113.         parms.pm_vers = version;
  2114.         parms.pm_prot = protocol;
  2115.         parms.pm_port = 0;  /* not needed or used */
  2116.         if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
  2117.             xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
  2118.             rpc_createerr.cf_stat = RPC_PMAPFAILURE;
  2119.             clnt_geterr(client, &rpc_createerr.cf_error);
  2120.         } else if (port == 0) {
  2121.             rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
  2122.         }
  2123.         CLNT_DESTROY(client);
  2124.     }
  2125.     (void)close(socket);
  2126.     address->sin_port = 0;
  2127.     return (port);
  2128. }
  2129. Funky_Stuff
  2130. len=`wc -c < pmap_getport.c`
  2131. if [ $len !=     2846 ] ; then
  2132.   echo error: pmap_getport.c was $len bytes long, should have been     2846
  2133. fi
  2134. echo x - pmap_prot.c
  2135. cat > pmap_prot.c <<'Funky_Stuff'
  2136. /* @(#)pmap_prot.c    1.1 87/11/04 3.9 RPCSRC */
  2137. /*
  2138.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  2139.  * unrestricted use provided that this legend is included on all tape
  2140.  * media and as a part of the software program in whole or part.  Users
  2141.  * may copy or modify Sun RPC without charge, but are not authorized
  2142.  * to license or distribute it to anyone else except as part of a product or
  2143.  * program developed by the user.
  2144.  * 
  2145.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  2146.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  2147.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  2148.  * 
  2149.  * Sun RPC is provided with no support and without any obligation on the
  2150.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  2151.  * modification or enhancement.
  2152.  * 
  2153.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  2154.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  2155.  * OR ANY PART THEREOF.
  2156.  * 
  2157.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  2158.  * or profits or other special, indirect and consequential damages, even if
  2159.  * Sun has been advised of the possibility of such damages.
  2160.  * 
  2161.  * Sun Microsystems, Inc.
  2162.  * 2550 Garcia Avenue
  2163.  * Mountain View, California  94043
  2164.  */
  2165. #if !defined(lint) && defined(SCCSIDS)
  2166. static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
  2167. #endif
  2168.  
  2169. /*
  2170.  * pmap_prot.c
  2171.  * Protocol for the local binder service, or pmap.
  2172.  *
  2173.  * Copyright (C) 1984, Sun Microsystems, Inc.
  2174.  */
  2175.  
  2176. #include <rpc/types.h>
  2177. #include <rpc/xdr.h>
  2178. #include <rpc/pmap_prot.h>
  2179.  
  2180.  
  2181. bool_t
  2182. xdr_pmap(xdrs, regs)
  2183.     XDR *xdrs;
  2184.     struct pmap *regs;
  2185. {
  2186.  
  2187.     if (xdr_u_long(xdrs, ®s->pm_prog) && 
  2188.         xdr_u_long(xdrs, ®s->pm_vers) && 
  2189.         xdr_u_long(xdrs, ®s->pm_prot))
  2190.         return (xdr_u_long(xdrs, ®s->pm_port));
  2191.     return (FALSE);
  2192. }
  2193. Funky_Stuff
  2194. len=`wc -c < pmap_prot.c`
  2195. if [ $len !=     1879 ] ; then
  2196.   echo error: pmap_prot.c was $len bytes long, should have been     1879
  2197. fi
  2198. cd ..
  2199. echo more files to follow
  2200. exit
  2201.